




public class FIR_13taps_256samples_mapping extends FIR_Filter_Mapping implements
		Interface_FIR_Mapping {

//Cfu.Instruction_List instruction;
	
//	public FIR_13taps_256samples_mapping(Instruction_List instruction)
//	{
//		this.instruction = instruction;
//	}
	
	
	public void Load_Coefficients_into_CFUs() {
		/*
		 * Note: Channels are mapped horizontallyIt is assumed that FIR filter
		 * coefficients are stored in the initial part of the RAMThis loading
		 * function is for 13 FIR filter (Currently suitable for 8x8 array).
		 */

		int cfu_row_index = 0, cfu_column_index = 0;
		for (int channelNo = 0; channelNo < no_channels_int; channelNo++) {
			/*
			 * We load same coefficient in no_cfu_per_channel for multiple
			 * channel processing. So, we will start loading coefficients again
			 */

			ram_read_index = 0;
			for (int cfuNo = 0; cfuNo < no_cfu_per_channel; cfuNo++) {
				if (cfu_column_index == no_cfu_column_int - 1) {
					// Move to next row
					cfu_row_index++;
					// Start from the first column of the next row
					cfu_column_index = 0;

				} else {
					Cfu_Array[cfu_row_index][cfu_column_index].update_register(
							0, fir_ram.ram[ram_read_index]);

					// increase column index and move forward to next CFU
					cfu_column_index++;

					// Read next data from RAM
					ram_read_index++;
					fir_ram.RAM_accesses++;
				}
			}
		}
	}

	public void Load_Data_into_CFUs() {

		/*
		 * Note: Channels are mapped horizontally
		 */

		/*
		 * It is assumed that FIR filter coefficients are stored in the initial
		 * part of the RAM
		 */

		// Start reading Data from Ram next from the last coefficient
		ram_read_index = last_ram_read_index;
		// System.out.println("ram_read_index="+ ram_read_index);
		// System.out.println("last_ram_read_index="+ last_ram_read_index);

		int cfu_row_index = 0, cfu_column_index = 0;
		// for (int channelNo=0;channelNo<no_channels_int; channelNo++)
		{

			for (int cfuNo = 0; cfuNo < no_cfu_per_channel; cfuNo++) {
				if (cfu_column_index == no_cfu_column_int - 1) {
					// Move to next row
					cfu_row_index++;
					// Start from the first column of the next row
					cfu_column_index = 0;

				} else {
					Cfu_Array[cfu_row_index][cfu_column_index].update_register(
							1, fir_ram.ram[ram_read_index]);

					// increase column index and move forward to next CFU
					cfu_column_index++;

					// Read next data from RAM
					ram_read_index--;
					fir_ram.RAM_accesses++;
				}
			}
		}

		/*
		 * Store the index of last Data loaded in the CFU so that next round of
		 * the loading can be started from there.
		 */

		last_ram_read_index = ram_read_index;

	}

	public void Configure_CFUs() {
		int cfu_row_index = 0, cfu_column_index = 0;
		// Configure CFUs for MAC operations

		for (int channelNo = 0; channelNo < no_channels_int; channelNo++) {

			for (int cfuNo = 0; cfuNo < no_cfu_per_channel; cfuNo++) {
				if (cfu_column_index == no_cfu_column_int - 1) {
					// Move to next row
					cfu_row_index++;
					// Start from the first column of the next row
					cfu_column_index = 0;

				}

				else {
					
					Cfu_Array[cfu_row_index][cfu_column_index].Cfu_initialize(
							Cfu.Instruction_List.MAC, 0, 1, 2, 3, 4, FIR_SCALING_FACTOR,0xFFFF);
					// System.out.println("Cfu_Array [" + cfu_row_index + "][" +
					// (cfu_column_index) + "] Intialized");
					// increase column index and move forward to next CFU
					cfu_column_index++;
				}

			}
		}

		// Configure CFUs for final addition operation
		cfu_row_index = 1;
		// System.out.println ("Initializing for final ADD operations...");
		for (int channelNo = 0; channelNo < no_channels_int; channelNo++) {

			Cfu_Array[cfu_row_index][no_cfu_column_int - 1].Cfu_initialize(Cfu.Instruction_List.ADD,
					0, 1, 2, 3, 4, 0,0xFFFF);
			// System.out.println("Cfu_Array [" + cfu_row_index + "][" +
			// (no_cfu_column_int-1) + "] Initialized");
			cfu_row_index = cfu_row_index + 2;

		}

		 //Configure CFUs for shift operation
		 cfu_row_index = 0;
		 System.out.println ("Initializing for final Shift operations...");
		 for (int channelNo=0;channelNo<no_channels_int; channelNo++)
		 {
		
		 Cfu_Array[cfu_row_index][no_cfu_column_int-1].Cfu_initialize(Cfu.Instruction_List.SHIFT_RIGHT,0,1,
		 2, 3,4, FIR_SCALING_FACTOR,0xffff);
		 //System.out.println("Cfu_Array [" + cfu_row_index + "][" + (no_cfu_column_int-1) + "] Intialized");
		 cfu_row_index = cfu_row_index+2;
		
		 }

		// //Configure CFUs for final addition operation
		// cfu_row_index = 1;
		// for (int channelNo=0;channelNo<no_channels_int; channelNo++)
		// {
		//			
		// Cfu_Array[cfu_row_index][no_cfu_column_int-1].Cfu_initialize(ADD,0,1,
		// 2, 3, 0);
		// cfu_row_index = cfu_row_index+2;
		//			
		// }
		//			
		// //Configure CFUs for shift operation
		// cfu_row_index = 0;
		// for (int channelNo=0;channelNo<no_channels_int; channelNo++)
		// {
		//			
		// Cfu_Array[cfu_row_index][no_cfu_column_int-1].Cfu_initialize(SHIFT_RIGHT,0,1,
		// 2, 3, fir_scaling_factor);
		// cfu_row_index = cfu_row_index+2;
		//			
		// }
	}

	public void Run_CFUs() {
		// int cfu_row_index = 0, cfu_column_index =0;

		// System.out.println("In 0 "+fir_ram.ram[2*no_taps_int]);
		// System.out.println("In 1 "+fir_ram.ram[2*no_taps_int +
		// no_cfu_column_int-1]);
		//
		// System.out.println("In 0 "+fir_ram.ram[fir_ram.ram[0]]);
		// System.out.println("In 1 "+fir_ram.ram[no_cfu_column_int-1]);

		Configure_CFUs();

		// Loading filter coefficients

		Load_Coefficients_into_CFUs();

		// Because we will start from reverse
		last_ram_read_index = (2 * (no_taps_int+1))-1;

		Load_Data_into_CFUs();

		// Cfu_Array[0][0].update_register(0,fir_ram.ram[0]);
		// Cfu_Array[1][0].update_register(0, fir_ram.ram[no_cfu_column_int-1]);

		int Cycle = 0;
		// ==================================
		// Cycle 1.1


//		for (int m = 0; m <= Cycle; m++)
//		// for(int m=0;m<=1;m++)
//		{
//
//			for (int n = 0; n < Cycle; n++)
//			// for(int n=0;n<=1;n++)
//			{
//				Cfu_Array[m][n].start_CFU();
//			}
//		}

		Cycle = 1;
		
		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();
		
		
		
		Cycle = 2;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		Cycle = 3;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		Cycle = 4;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		Cycle = 5;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		Cycle = 6;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		Cycle = 7;
		Cfu_Array[0][Cycle - 1].update_register(2,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(2,
				Cfu_Array[1][Cycle - 2].register_array[4]);

		Cfu_Array[0][Cycle - 1].start_CFU();
		Cfu_Array[1][Cycle - 1].start_CFU();

//		Cfu_Array[0][Cycle - 1].start_CFU();
//		Cfu_Array[1][Cycle - 1].start_CFU();

		// Final addition operation

		Cycle = 8;
		Cfu_Array[1][Cycle - 1].update_register(0,
				Cfu_Array[0][Cycle - 2].register_array[4]);
		Cfu_Array[1][Cycle - 1].update_register(1,
				Cfu_Array[1][Cycle - 2].register_array[4]);
		
		Cfu_Array[1][Cycle - 1].start_CFU();

		//Perform the final shift operation
		
		Cycle = 9;
		Cfu_Array[0][7].update_register(0,
				Cfu_Array[1][7].register_array[4]);
		
		Cfu_Array[0][7].start_CFU();

		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < no_cfu_column_int; y++) {
				for (int i = 0; i < Cfu_Array[1][0].register_array.length; i++)
					System.out.println("CFU Array [" + x + "][" + y + "]: "
							+ "register[" + i + "]="
							+ Cfu_Array[x][y].register_array[i]);
			}
		}

		// ==========================================
		// Cycle 2.1
		// Cycle =2;
		// Cfu_Array[0][0].update_register(2,fir_ram.ram[2*no_taps_int+1] );
		// Cfu_Array[1][0].update_register(2, fir_ram.ram[2*no_taps_int+1 +
		// no_cfu_column_int-1]);
		//
		//
		// for(int m=0;m<Cycle;m++)
		// //for(int m=0;m<=1;m++)
		// {
		//
		// for(int n=0;n<Cycle;n++)
		// //for(int n=0;n<=1;n++)
		// {
		// Cfu_Array[m][n].start_CFU();
		// }
		// }

		// Cfu_Array[0][0].start_CFU();
		// Cfu_Array[1][0].start_CFU();

		// System.out.println("Register Access Count = " +
		// Cfu.Register_Accesses);

		// Displaying all the registers of all the CFUs.
		// for (int x=0;x<no_cfu_row_int;x++)
		// {
		// for (int y=0;y<no_cfu_column_int;y++)
		// {
		// for (int i=0;i<Cfu_Array[1][0].register_array.length;i++)
		// System.out.println("register["
		// +i+"]="+Cfu_Array[x][y].register_array[i]);
		// }
		// }

		// for (int x=0;x<2;x++)
		// {
		// for (int y=0;y<8;y++)
		// {
		// for (int i=0;i<Cfu_Array[1][0].register_array.length;i++)
		// System.out.println("register["
		// +i+"]="+Cfu_Array[x][y].register_array[i]);
		// }
		// }
		//		
	}

	public void Get_Output() {

	}

	public void Get_Statastics() {
		Form_Statistics_FIR13taps256samples.main(null);

	}

}